import struct

from enums.modbus_register import DecodeType, ByteOrder, InnerDecode


class Decode:
    byteorder_mapping = {
        InnerDecode.UnsignedShort: ByteOrder.BigEndUnsignedShort.value,
        InnerDecode.SignedShort: ByteOrder.BigEndSignedShort.value,
        InnerDecode.LongABCD: ByteOrder.BigEndSignedInt.value,
        InnerDecode.LongCDAB: ByteOrder.BigEndWordSwappedSignedInt.value,
        InnerDecode.LongBADC: ByteOrder.LittleEndWordSwappedSignedInt.value,
        InnerDecode.LongDCBA: ByteOrder.LittleEndSignedInt.value,
        InnerDecode.FloatABCD: ByteOrder.BigEndFloat.value,
        InnerDecode.FloatCDAB: ByteOrder.WordSwappedFloat.value,
        InnerDecode.FloatBADC: ByteOrder.LittleEndWordSwappedFloat.value,
        InnerDecode.FloatDCBA: ByteOrder.LittleEndFloat.value,
    }

    def __init__(self):
        pass

    @classmethod
    def get_byteorder(cls, decode: InnerDecode) -> str:
        return cls.byteorder_mapping.get(decode, ByteOrder.BigEndSignedShort.value)

    @staticmethod
    def pack_value(byteorder: str, value) -> bytes:
        """
        支持整数和浮点数字节序打包（含字交换）
        """
        if byteorder.endswith("_"):  # 处理所有字交换情况
            fmt = byteorder[:-1]
            packed = struct.pack(fmt, float(value) if "f" in fmt else int(value))
            # 通用字交换逻辑（2字节为单位）
            if len(packed) >= 4:  # 4字节及以上数据
                return b"".join(
                    packed[i + 2:i + 4] + packed[i:i + 2]  # 交换高低16位
                    for i in range(0, len(packed), 4)
                )
            return packed[::-1]  # 小于4字节的数据整体反转
        return struct.pack(byteorder, float(value) if "f" in byteorder else int(value))

    @staticmethod
    def unpack_value(byteorder: str, buffer: bytes):
        """支持整数和浮点数字节序解包（含字交换）"""
        if byteorder.endswith("_"):  # 处理所有字交换情况
            fmt = byteorder[:-1]
            # 反向字交换
            if len(buffer) >= 4:
                swapped = b"".join(
                    buffer[i + 2:i + 4] + buffer[i:i + 2]  # 交换高低16位
                    for i in range(0, len(buffer), 4)
                )
            else:
                swapped = buffer[::-1]
            return struct.unpack(fmt, swapped)[0]
        return struct.unpack(byteorder, buffer)[0]
